﻿<demo:DemoViewBase x:Name="_root"
	x:Class="MenuDemo.MenuDemoView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	xmlns:local="clr-namespace:MenuDemo"
	xmlns:demo="clr-namespace:DemoSupport;assembly=DemoSupport"
	xmlns:sys="clr-namespace:System;assembly=mscorlib">
	<demo:DemoViewBase.Resources>
		<DrawingImage x:Key="MenuItemImage">
			<DrawingImage.Drawing>
				<DrawingGroup>
					<DrawingGroup.Children>
						<GeometryDrawing Brush="#ff7e7e7e" Geometry="F1 M 51.351563,43.402832 C 37.662109,13.375000 14.479004,20.440430 14.258301,20.440430 L 14.258301,30.375977 L 0.900391,14.368652 L 14.368652,0.900391 L 14.368652,10.946289 C 14.368652,10.946289 46.494141,3.439453 51.351563,43.402832 Z">
							<GeometryDrawing.Pen>
								<Pen DashCap="Flat" Thickness="1.800910" Brush="#ff323232" StartLineCap="Round" EndLineCap="Round" LineJoin="Round"/>
							</GeometryDrawing.Pen>
						</GeometryDrawing>
					</DrawingGroup.Children>
				</DrawingGroup>
			</DrawingImage.Drawing>
		</DrawingImage>
	</demo:DemoViewBase.Resources>
	
	<Grid>
		<Grid.RowDefinitions>
			<RowDefinition Height="*"/>
		</Grid.RowDefinitions>
		<Grid.ColumnDefinitions>
			<ColumnDefinition Width="1*"/>
			<ColumnDefinition Width="Auto"/>
			<ColumnDefinition Width="2*"/>
		</Grid.ColumnDefinitions>

		<FlowDocumentScrollViewer DataContext="{Binding ElementName=_root}" VerticalScrollBarVisibility="Auto">
			<FlowDocument>
				<Paragraph>
					<Span Style="{DynamicResource Heading1}">Menu Service</Span>
				</Paragraph>
				<Paragraph>
					The shell provides a menu service. This service is an implementation of the
					<Span Style="{DynamicResource Code}">IMenuService</Span> interface, and it allows module developers to easily add menu
					items to appropriate extension points in the shell. Typically it would be used to extend the main menu or context menus.
					It is used in conjunction with the command service, which allows you to wrap either a CAB or WPF command instance for
					consumption by the menu service.
				</Paragraph>
				<Paragraph>
					The menu service has several features that make it easier for module developers to get their job done without getting
					side-tracked by issues related to shell integration. It is also designed in such a way as to minimize UI-specific code in
					your business logic. For example, you won't work directly with WPF's <Span Style="{StaticResource Code}">MenuItem</Span>
					class, but will instead work against an interface provided with the shell.
				</Paragraph>
				<Paragraph>
					When you add a menu item using the menu service, you can specify a group index. Any menu items in the same group are kept
					together and separated by a WPF <Span Style="{StaticResource Code}">Separator</Span> instance. This is done automatically
					and intelligently - separators will appear and disappear to adjust to their surrounding menu items.
				</Paragraph>
				<Paragraph>
					You can also specify an index when adding a menu item. This allows you to specify the relative position of the menu item
					<Italic>within its group</Italic>. For example, a menu item with an index of 10 will appear after (below) a menu item
					with an index of 5. Staggering indexes makes it possible for other modules to insert their menu items in between yours, or
					in between those provided by the shell.
				</Paragraph>
				<Paragraph>
					When you add a menu item, you might not want to associate a command with it. The menu item may be intended as a container
					for other menu items. For example, the <Span Style="{StaticResource Code}">View / Toolbars</Span> menu item provided by the
					shell exists only to house other menu items, one for each tool bar. If you do not provide a command when creating your menu
					item, the shell will automatically ensure that the menu item is visible only when it has children.
				</Paragraph>
			</FlowDocument>
		</FlowDocumentScrollViewer>
		
		<GridSplitter Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Stretch"/>

		<demo:DemoSet Grid.Column="2">
			<demo:DemoSet.CommandBindings>
				<CommandBinding Command="{x:Static local:MenuDemoView.Example1AddTopLevelMenuItem}" CanExecute="Example1AddTopLevelMenuItem_CanExecute" Executed="Example1AddTopLevelMenuItem_Executed"/>
				<CommandBinding Command="{x:Static local:MenuDemoView.Example1AddChildMenuItem}" CanExecute="Example1AddChildMenuItem_CanExecute" Executed="Example1AddChildMenuItem_Executed"/>
				<CommandBinding Command="{x:Static local:MenuDemoView.Example1RemoveChildMenuItem}" CanExecute="Example1RemoveChildMenuItem_CanExecute" Executed="Example1RemoveChildMenuItem_Executed"/>
				<CommandBinding Command="{x:Static local:MenuDemoView.Example1RemoveTopLevelMenuItem}" CanExecute="Example1RemoveTopLevelMenuItem_CanExecute" Executed="Example1RemoveTopLevelMenuItem_Executed"/>

				<CommandBinding Command="{x:Static local:MenuDemoView.Example2AddMenuItemWithImage}" CanExecute="Example2AddMenuItemWithImage_CanExecute" Executed="Example2AddMenuItemWithImage_Executed"/>
				<CommandBinding Command="{x:Static local:MenuDemoView.Example2AddCheckableMenuItem}" CanExecute="Example2AddCheckableMenuItem_CanExecute" Executed="Example2AddCheckableMenuItem_Executed"/>
				<CommandBinding Command="{x:Static local:MenuDemoView.Example2CheckUncheckMenuItem}" CanExecute="Example2CheckUncheckMenuItem_CanExecute" Executed="Example2CheckUncheckMenuItem_Executed"/>
				<CommandBinding Command="{x:Static local:MenuDemoView.Example2CleanUp}" CanExecute="Example2CleanUp_CanExecute" Executed="Example2CleanUp_Executed"/>

				<CommandBinding Command="{x:Static local:MenuDemoView.Example3AddSortedMenuItem}" CanExecute="Example3AddSortedMenuItem_CanExecute" Executed="Example3AddSortedMenuItem_Executed"/>
				<CommandBinding Command="{x:Static local:MenuDemoView.Example3AddGroupedMenuItem}" CanExecute="Example3AddGroupedMenuItem_CanExecute" Executed="Example3AddGroupedMenuItem_Executed"/>
				<CommandBinding Command="{x:Static local:MenuDemoView.Example3AddGroupedAndSortedMenuItems}" CanExecute="Example3AddGroupedAndSortedMenuItems_CanExecute" Executed="Example3AddGroupedAndSortedMenuItems_Executed"/>
				<CommandBinding Command="{x:Static local:MenuDemoView.Example3CleanUp}" CanExecute="Example3CleanUp_CanExecute" Executed="Example3CleanUp_Executed"/>

				<CommandBinding Command="{x:Static local:MenuDemoView.Example4AddParentMenuItem}" CanExecute="Example4AddParentMenuItem_CanExecute" Executed="Example4AddParentMenuItem_Executed"/>
				<CommandBinding Command="{x:Static local:MenuDemoView.Example4AddChildMenuItems}" CanExecute="Example4AddChildMenuItems_CanExecute" Executed="Example4AddChildMenuItems_Executed"/>
				<CommandBinding Command="{x:Static local:MenuDemoView.Example4CleanUp}" CanExecute="Example4CleanUp_CanExecute" Executed="Example4CleanUp_Executed"/>
			</demo:DemoSet.CommandBindings>
			
			<demo:Demo Title="Adding a Menu Item">
				<demo:Demo.Description>
					This example demonstrates how to add a menu item using the menu service. It also demonstrates how the menu
								service will automatically ensure the menu items are hidden or displayed according to some simple rules.
				</demo:Demo.Description>
				<demo:Step Title="Add a top-level menu item" Command="{x:Static local:MenuDemoView.Example1AddTopLevelMenuItem}">
					<demo:Step.Header>
						This step adds a top-level menu item in between the File and Edit menu items.
					</demo:Step.Header>
					<demo:Step.Code>
						<sys:String xml:space="preserve">ICommand command = _commandService.CreateCommand("Top Level Item", null);
_topLevelMenuItem = _menuService.Add(ExtensionSites.Menu.Name, command, ExtensionSites.Menu.File.GroupIndex, ExtensionSites.Menu.File.Index + 1, _topLevelMenuItemSiteName);</sys:String>					</demo:Step.Code>
					<demo:Step.Footer>
						Notice how the menu item is not visible after it is added. This is because it does not have a command
									associated with it and does not yet have any children.
					</demo:Step.Footer>
				</demo:Step>
				<demo:Step Title="Add a child menu item" Command="{x:Static local:MenuDemoView.Example1AddChildMenuItem}">
					<demo:Step.Header>
						This step adds a child menu item to the top-level menu item added above.
					</demo:Step.Header>
					<demo:Step.Code>
						<sys:String xml:space="preserve">ICommand childCommand = _commandService.CreateCommand(WorkItem.Commands["ChildMenuItem"], "Child Menu Item", null);
_childMenuItem = _menuService.Add(_topLevelMenuItemSiteName, childCommand, null, null, null);</sys:String>					</demo:Step.Code>
					<demo:Step.Footer>
						Notice how the top-level menu item becomes visible after adding the child menu item. Try clicking on the child
								menu item.
					</demo:Step.Footer>
				</demo:Step>
				<demo:Step Title="Remove child menu item" Command="{x:Static local:MenuDemoView.Example1RemoveChildMenuItem}">
					<demo:Step.Header>
						This step removes the child menu item that was added above.
					</demo:Step.Header>
					<demo:Step.Code>
						<sys:String xml:space="preserve">_menuService.Remove(_childMenuItem);</sys:String>					</demo:Step.Code>
					<demo:Step.Footer>
						Notice how the top-level menu item is no longer visible after executing this step. It is still there, but
									the shell takes care of automatically hiding it.
					</demo:Step.Footer>
				</demo:Step>
				<demo:Step Title="Remove the top-level menu item" Command="{x:Static local:MenuDemoView.Example1RemoveTopLevelMenuItem}">
					<demo:Step.Header>
						This step removes the top-level menu item that was added in the first step.
					</demo:Step.Header>
					<demo:Step.Code>
						<sys:String xml:space="preserve">_menuService.Remove(_topLevelMenuItem);</sys:String>					</demo:Step.Code>
					<demo:Step.Footer>
						After executing this step, the top-level menu item is completely removed. The shell takes cares of unregistering
									the extension point too.
					</demo:Step.Footer>
				</demo:Step>
			</demo:Demo>
			
			<demo:Demo Title="Customizing Menu Items">
				<demo:Demo.Description>
					This example demonstrates how menu items yielded by the menu service can be customized.
				</demo:Demo.Description>
				<demo:Step Title="Add a menu item with an image" Command="{x:Static local:MenuDemoView.Example2AddMenuItemWithImage}">
					<demo:Step.Header>
						This step adds a menu item that has an image associated with it.
					</demo:Step.Header>
					<demo:Step.Code>
						<sys:String xml:space="preserve">ICommand command = _commandService.CreateCommand(WorkItem.Commands["ChildMenuItem"], "Menu Item With Image", View.MenuItemImage);
_menuItemWithImage = _menuService.Add(ExtensionSites.Menu.File.Name, command, null, null, null);</sys:String>					</demo:Step.Code>
					<demo:Step.Footer>
						Take a look in the File menu after executing this step. You'll see a menu item with an image. You can try executing
							the menu item too.
					</demo:Step.Footer>
				</demo:Step>
				<demo:Step Title="Add a checkable menu item" Command="{x:Static local:MenuDemoView.Example2AddCheckableMenuItem}">
					<demo:Step.Header>
						This step adds a menu item that will be used to demonstrate checking / unchecking.
					</demo:Step.Header>
					<demo:Step.Code>
						<sys:String xml:space="preserve">ICommand command = _commandService.CreateCommand(WorkItem.Commands["ChildMenuItem"], "Menu Item With CheckBox", null);
_menuItemForChecking = _menuService.Add(ExtensionSites.Menu.File.Name, command, null, null, null);</sys:String>					</demo:Step.Code>
					<demo:Step.Footer>
						Take a look in the File menu after executing this step. You'll see a new menu item that is currently unchecked.
					</demo:Step.Footer>
				</demo:Step>
				<demo:Step Title="Checking / unchecking the menu item" Command="{x:Static local:MenuDemoView.Example2CheckUncheckMenuItem}">
					<demo:Step.Header>
						This step checks and unchecks the menu item added in the previous step. Try executing this step and then look in
						the File menu.
					</demo:Step.Header>
					<demo:Step.Code>
						<sys:String xml:space="preserve">_menuItemForChecking.IsChecked = !_menuItemForChecking.IsChecked;</sys:String>					</demo:Step.Code>
				</demo:Step>
				<demo:Step Title="Clean up" Command="{x:Static local:MenuDemoView.Example2CleanUp}">
					<demo:Step.Header>
						This step just cleans up the added menu items, allowing you to start the demo again.
					</demo:Step.Header>
				</demo:Step>
			</demo:Demo>

			<demo:Demo Title="Sorting and Grouping Menu Items">
				<demo:Demo.Description>
					This example demonstrates the sorting and grouping facilities provided by the menu service.
				</demo:Demo.Description>
				<demo:Step Title="Add a sorted menu item" Command="{x:Static local:MenuDemoView.Example3AddSortedMenuItem}">
					<demo:Step.Header>
						This step inserts a menu item between existing menu items provided by the shell. It does this by specifying an
						appropriate index for the menu item.
					</demo:Step.Header>
					<demo:Step.Code>
						<sys:String xml:space="preserve">ICommand command = _commandService.CreateCommand(WorkItem.Commands["ChildMenuItem"], "Sorted Menu Item", null);
_sortedMenuItem = _menuService.Add(ExtensionSites.Menu.Edit.Name, command, ExtensionSites.Menu.Edit.Copy.GroupIndex, ExtensionSites.Menu.Edit.Copy.Index + 1, null);</sys:String>					</demo:Step.Code>
					<demo:Step.Footer>
						Take a look in the Edit menu after executing this step. You'll see a new menu item between the Copy and Paste menu
						items.
					</demo:Step.Footer>
				</demo:Step>
				<demo:Step Title="Add a grouped menu item" Command="{x:Static local:MenuDemoView.Example3AddGroupedMenuItem}">
					<demo:Step.Header>
						This step adds a menu item in a new group to the Edit menu.
					</demo:Step.Header>
					<demo:Step.Code>
						<sys:String xml:space="preserve">ICommand command = _commandService.CreateCommand(WorkItem.Commands["ChildMenuItem"], "Grouped Menu Item", null);
_groupedMenuItem = _menuService.Add(ExtensionSites.Menu.Edit.Name, command, ExtensionSites.Menu.Edit.Copy.GroupIndex + 1, 0, null);</sys:String>					</demo:Step.Code>
					<demo:Step.Footer>
						Take a look in the Edit menu after executing this step. You'll see a new menu item in its own group in between two
						existing groups. The menu service automatically takes care of ensuring separators are added in the appropriate
						places.
					</demo:Step.Footer>
				</demo:Step>
				<demo:Step Title="Add grouped and sorted menu items" Command="{x:Static local:MenuDemoView.Example3AddGroupedAndSortedMenuItems}">
					<demo:Step.Header>
						This step adds two more menu items to the new group add above. It again uses indexes to ensure the menu items appear
						in certain positions. Note that the indexes apply within the group only.
					</demo:Step.Header>
					<demo:Step.Code>
						<sys:String xml:space="preserve">ICommand command1 = _commandService.CreateCommand(WorkItem.Commands["ChildMenuItem"], "Grouped and Sorted Menu Item 1", null);
ICommand command2 = _commandService.CreateCommand(WorkItem.Commands["ChildMenuItem"], "Grouped and Sorted Menu Item 2", null);
_groupedAndSortedMenuItem1 = _menuService.Add(ExtensionSites.Menu.Edit.Name, command1, ExtensionSites.Menu.Edit.Copy.GroupIndex + 1, 1, null);
_groupedAndSortedMenuItem2 = _menuService.Add(ExtensionSites.Menu.Edit.Name, command2, ExtensionSites.Menu.Edit.Copy.GroupIndex + 1, -1, null);</sys:String>					</demo:Step.Code>
					<demo:Step.Footer>
						Take another look in the Edit menu after executing this step. You'll see two more menu items in the group - one on
						either side of the menu item added above.
					</demo:Step.Footer>
				</demo:Step>
				<demo:Step Title="Clean up" Command="{x:Static local:MenuDemoView.Example3CleanUp}">
					<demo:Step.Header>
						This step just cleans up the added menu items, allowing you to start the demo again.
					</demo:Step.Header>
				</demo:Step>
			</demo:Demo>

			<demo:Demo Title="Sub menus">
				<demo:Demo.Description>
					This example demonstrates how sub menus can be created with the menu service.
				</demo:Demo.Description>
				<demo:Step Title="Add a parent menu item" Command="{x:Static local:MenuDemoView.Example4AddParentMenuItem}">
					<demo:Step.Header>
						This step inserts a parent menu item to host the children.
					</demo:Step.Header>
					<demo:Step.Code>
						<sys:String xml:space="preserve">ICommand command = _commandService.CreateCommand("Parent Menu Item", null);
_parentMenuItem = _menuService.Add(ExtensionSites.Menu.File.Name, command, null, null, "SiteName");</sys:String>					</demo:Step.Code>
					<demo:Step.Footer>
						After executing, the parent menu item will have been added to the File menu. However, it won't be visible because it
						has no children yet.
					</demo:Step.Footer>
				</demo:Step>
				<demo:Step Title="Add child menu items" Command="{x:Static local:MenuDemoView.Example4AddChildMenuItems}">
					<demo:Step.Header>
						This step adds child menu items to the parent menu item.
					</demo:Step.Header>
					<demo:Step.Code>
						<sys:String xml:space="preserve">ICommand command1 = _commandService.CreateCommand(WorkItem.Commands["ChildMenuItem"], "Child Menu Item 1", null);
ICommand command2 = _commandService.CreateCommand(WorkItem.Commands["ChildMenuItem"], "Child Menu Item 2", null);
_childMenuItem1 = _menuService.Add("SiteName", command1, null, null, null);
_childMenuItem2 = _menuService.Add("SiteName", command2, null, null, null);</sys:String>					</demo:Step.Code>
					<demo:Step.Footer>
						After executing this step, you will see the parent menu item inside the File menu, along with its children in a
						sub menu.
					</demo:Step.Footer>
				</demo:Step>
				<demo:Step Title="Clean up" Command="{x:Static local:MenuDemoView.Example4CleanUp}">
					<demo:Step.Header>
						This step just cleans up the added menu items, allowing you to start the demo again.
					</demo:Step.Header>
				</demo:Step>
			</demo:Demo>
		</demo:DemoSet>
	</Grid>
</demo:DemoViewBase>
